package net.sf.calibur.pool;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;

import net.sf.calibur.util.Util;

/**
 * 借出对象跟踪
 * @author gaobo.benny
 *
 */
class ActiveObjectTrace {
	Object object;
	Thread holder;
	long timestamp;
	StackTraceElement[] stackTrace;

	public ActiveObjectTrace() {
		clear();
	}
	
	public void touch(Object object) {
		this.object = object;
		timestamp = System.currentTimeMillis();
		holder = Thread.currentThread();
		stackTrace = Thread.currentThread().getStackTrace();
	}
	
	public void clear() {
		object = null;
		holder = null;
		timestamp = 0;
		stackTrace = null;
	}

	public long getHoldTime() {
		return System.currentTimeMillis() - timestamp;
	}

	@Override
	public String toString() {
		return toString(null);
	}
	
	public String toString(Collection<String> filters) {
		if (timestamp == 0) {
			return "empty";
		}
		
		StringWriter sw = new StringWriter();
		PrintWriter ps = new PrintWriter(sw);
		int time = (int) (getHoldTime() / 1000L);
		ps.printf("class=%s time=%ds stackTrace:", object.getClass().getName(), time);
		for (StackTraceElement e : stackTrace) {
			if (doFilter(e, filters)) {
				ps.println(e);
			}
		}
		return sw.toString();
	}
	
	private boolean doFilter(StackTraceElement e, Collection<String> filters) {
		String clazz = e.getClassName();
		if (clazz.startsWith("java.")) {
			return false;
		} else if (clazz.equals(getClass().getName())) {
			return false;
		} else if (Util.isEmpty(filters)) {
			return true;
		} else {
			for (String filter : filters) {
				if (clazz.startsWith(filter)) {
					return true;
				}
			}

			return false;
		}
	}
}

